<template>
  <div class="chart-container">
    <div
      ref="chartRef"
      :style="{ width: width, height: height }"
      class="chart"
    />
  </div>
</template>

<script setup lang="ts">
import { computed, ref, onMounted, onUnmounted, watch } from "vue";

interface Props {
  type: "line" | "bar" | "pie" | "scatter" | "radar" | "gauge";
  data: any;
  title?: string;
  width?: string;
  height?: string;
  colors?: string[];
}

const props = withDefaults(defineProps<Props>(), {
  title: "",
  width: "100%",
  height: "400px",
  colors: () => ["#409EFF", "#67C23A", "#E6A23C", "#F56C6C", "#909399"],
});

const chartRef = ref<HTMLDivElement>();
let chartInstance: any = null;

const chartOption = computed(() => {
  const baseOption = {
    title: {
      text: props.title,
      left: "center",
    },
    color: props.colors,
    tooltip: {
      trigger: "axis",
    },
    legend: {
      data: props.data.legend || [],
    },
    grid: {
      left: "3%",
      right: "4%",
      bottom: "3%",
      containLabel: true,
    },
  };

  switch (props.type) {
    case "line":
      return {
        ...baseOption,
        xAxis: {
          type: "category",
          data: props.data.xAxis || [],
        },
        yAxis: {
          type: "value",
        },
        series:
          props.data.series?.map((item: any) => ({
            name: item.name,
            type: "line",
            data: item.data,
            smooth: true,
          })) || [],
      };

    case "bar":
      return {
        ...baseOption,
        xAxis: {
          type: "category",
          data: props.data.xAxis || [],
        },
        yAxis: {
          type: "value",
        },
        series:
          props.data.series?.map((item: any) => ({
            name: item.name,
            type: "bar",
            data: item.data,
          })) || [],
      };

    case "pie":
      return {
        ...baseOption,
        series: [
          {
            name: props.data.name || "数据",
            type: "pie",
            radius: "50%",
            data: props.data.data || [],
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: "rgba(0, 0, 0, 0.5)",
              },
            },
          },
        ],
      };

    case "scatter":
      return {
        ...baseOption,
        xAxis: {
          type: "value",
        },
        yAxis: {
          type: "value",
        },
        series:
          props.data.series?.map((item: any) => ({
            name: item.name,
            type: "scatter",
            data: item.data,
          })) || [],
      };

    case "radar":
      return {
        ...baseOption,
        radar: {
          indicator: props.data.indicator || [],
        },
        series: [
          {
            name: props.data.name || "雷达图",
            type: "radar",
            data: props.data.data || [],
          },
        ],
      };

    case "gauge":
      return {
        series: [
          {
            name: props.data.name || "仪表盘",
            type: "gauge",
            data: props.data.data || [],
            min: props.data.min || 0,
            max: props.data.max || 100,
            splitNumber: props.data.splitNumber || 10,
            axisLine: {
              lineStyle: {
                width: 10,
              },
            },
            splitLine: {
              length: 15,
            },
            axisTick: {
              length: 12,
            },
            pointer: {
              length: "80%",
            },
          },
        ],
      };

    default:
      return baseOption;
  }
});

// 初始化图表
const initChart = () => {
  if (!chartRef.value) return;

  const { $echarts } = useNuxtApp();
  chartInstance = ($echarts as any).init(chartRef.value);
  chartInstance.setOption(chartOption.value);
};

// 更新图表
const updateChart = () => {
  if (chartInstance) {
    chartInstance.setOption(chartOption.value, true);
  }
};

// 销毁图表
const disposeChart = () => {
  if (chartInstance) {
    chartInstance.dispose();
    chartInstance = null;
  }
};

// 监听窗口大小变化
const handleResize = () => {
  if (chartInstance) {
    chartInstance.resize();
  }
};

// 生命周期
onMounted(() => {
  initChart();
  window.addEventListener("resize", handleResize);
});

onUnmounted(() => {
  window.removeEventListener("resize", handleResize);
  disposeChart();
});

// 监听数据变化
watch(
  chartOption,
  () => {
    updateChart();
  },
  { deep: true }
);

// 监听props变化
watch(
  () => [props.type, props.data, props.title],
  () => {
    updateChart();
  },
  { deep: true }
);
</script>

<style scoped>
.chart-container {
  width: 100%;
  height: 100%;
}

.chart {
  width: 100%;
  height: 100%;
}
</style>
